/**
 * Kernel Monkeys
 * Andrew Boguk
 * Sergiy Kulyk
 * Nicholas Swartzendruber
 */

/*
 * io_dev.c
 *
 * The IO Devices are activated, then signal
 * an interrupt when their service is completed.
 *
 *  Created on: June 6, 2011
 *      Author: Nicholas Swartzendruber
 */

#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <string.h>
#include "./io_dev.h"

/**
 * A main function for testing purposes.


int main() {
	io_dev io = io_dev_initialize(&test_print_io, DISK);
	io_dev_start(io);
	//Let it finish. (instead of joining)
	sleep(2);
}

*/


/**
 * Called to allocate memory for an io device. The device will be
 * started on its own thread.
 * @param func_ptr The function to call at the end of the service.
 * @return An io_dev pointer that may executed in it's own thread.
 */
io_dev io_dev_initialize(void (*func_ptr), char * type) {
	io_dev io = (io_dev) malloc(sizeof(io_str) + sizeof(char) * strlen(type));
	io->type = type;
	io->func_ptr = func_ptr;
	srand (time(NULL));
	return io;
}

/**
 * Called to start the passed io device.
 * This will start the service, and call the function
 * that was passed in initialize once it's done.
 * @return void
 */
void io_dev_start(io_dev io) {
	pthread_t pth;
	pthread_create(&pth, NULL, io_dev_thread_start, io);
	return;
}

/**
 * Helper method for starting a device on
 * it's own thread/running it.
 * @return void
 */
void * io_dev_thread_start(io_dev io) {
	int service_time = rand() % (MAX_WAIT - MIN_WAIT) + MIN_WAIT + 1;

	printf("IO Service / %s: Starting service. Estimated time: %dms\n", io->type, service_time);
	usleep(service_time * 1000);
	(io->func_ptr)();
	printf("IO Service / %s: completed.\n", io->type);

	return;
}

void test_print_io(){
	printf("This is a test print to simulate an io service triggering a function.\n");
}
